package conf_table

import (
	"encoding/json"
	"fmt"
	"go-iot-gateway/internal/conf_table/define"
	sqlite_conf_table "go-iot-gateway/internal/conf_table/impl/sqlite"
	sys_config "go-iot-gateway/internal/sys/config"
	sys_error "go-iot-gateway/internal/sys/errors"
	"strings"
)

// 初始化配置表
func InitConfTable(homeDir string, configInfo sys_config.ConfigTableEnv) error {
	fmt.Printf("\n===== 初始化CONF_TABLE ===== \n")
	jsonData, _ := json.Marshal(configInfo)
	fmt.Printf("%s \n", string(jsonData))

	switch configInfo.Type {
	case "sql":
		if strings.Contains(configInfo.Datasource.DriverClassName, "sqlite") ||
			strings.TrimSpace(configInfo.Datasource.DriverClassName) == "" {
			return sqlite_conf_table.LoadConfig(homeDir, configInfo)
		}
		panic("错误的典表配置sql驱动: " + configInfo.Datasource.DriverClassName)
	default:
		panic("错误的典表配置类型: " + configInfo.Type)
	}

}

//========= 通道管理 ========

// FindAllChannel 获取所有通道信息
func FindAllChannel() map[string]*conf_table_define.ChannelInfo {
	return sqlite_conf_table.ChannelInfoList()
}

// FindAllChannelList 获取所有通道
func FindAllChannelList() []*conf_table_define.ChannelInfo {
	resultList := make([]*conf_table_define.ChannelInfo, 0, 10)
	for _, ele := range sqlite_conf_table.ChannelInfoList() {
		resultList = append(resultList, ele)
	}
	return resultList
}

// FindTransferChannelList 查询转发通道列表
func FindTransferChannelList() []*conf_table_define.ChannelInfo {
	resultList := make([]*conf_table_define.ChannelInfo, 0, 10)
	for _, ele := range sqlite_conf_table.ChannelInfoList() {
		if ele.IsTransfer() {
			resultList = append(resultList, ele)
		}
	}
	return resultList
}

// FindAllChannelByName 根据名称查询通道
func FindAllChannelByName(Chl_name string) (*conf_table_define.ChannelInfo, error) {
	for _, ele := range sqlite_conf_table.ChannelInfoList() {
		if ele.Chl_name == Chl_name {
			return ele, nil
		}
	}
	return nil, sys_error.NOT_FOUND_ERR
}

func FindAllChannelByChlId(Chl_id string) (*conf_table_define.ChannelInfo, error) {
	if info, ok := sqlite_conf_table.ChannelInfoList()[Chl_id]; ok {
		return info, nil
	}
	return nil, sys_error.NOT_FOUND_ERR
}

// FindTag  获取标签信息，不包含转发通道的
func FindTag() map[string]*conf_table_define.TagInfo {
	return sqlite_conf_table.TagInfoList()
}

func FindAllTagByChlId(Chl_id string) []*conf_table_define.TagInfo {
	resultList := make([]*conf_table_define.TagInfo, 0, 700)

	channelConfInfo, err := FindAllChannelByChlId(Chl_id)
	if err != nil {
		return resultList
	}

	if channelConfInfo == nil {
		return resultList
	}

	if channelConfInfo.IsTransfer() {
		for _, ele := range sqlite_conf_table.TransferTagInfoList() {
			if ele.DeviceInfo.ChannelInfo.Chl_id == Chl_id {
				resultList = append(resultList, ele)
			}
		}
		return resultList
	}

	for _, ele := range sqlite_conf_table.TagInfoList() {
		if ele.DeviceInfo.ChannelInfo.Chl_id == Chl_id {
			resultList = append(resultList, ele)
		}
	}

	return resultList
}

func FindAllTagByTagType(Chl_id string, Tag_types ...int) []*conf_table_define.TagInfo {
	resultList := make([]*conf_table_define.TagInfo, 0, 250)
	if len(Tag_types) == 0 {
		return resultList
	}

	channelConfInfo, err := FindAllChannelByChlId(Chl_id)
	if err != nil {
		return resultList
	}

	if channelConfInfo == nil {
		return resultList
	}

	if channelConfInfo.IsTransfer() {
		for _, ele := range sqlite_conf_table.TransferTagInfoList() {
			if ele.DeviceInfo.ChannelInfo.Chl_id == Chl_id {
				for _, Tag_type := range Tag_types {
					if Tag_type == ele.Tag_type {
						resultList = append(resultList, ele)
					}
				}
			}
		}

		return resultList
	}

	for _, ele := range sqlite_conf_table.TagInfoList() {
		if ele.DeviceInfo.ChannelInfo.Chl_id == Chl_id {
			for _, Tag_type := range Tag_types {
				if Tag_type == ele.Tag_type {
					resultList = append(resultList, ele)
				}
			}
		}
	}

	return resultList
}

func FindAllTagByDeviceId(Dev_id string) []*conf_table_define.TagInfo {
	resultList := make([]*conf_table_define.TagInfo, 0, 250)

	deviceInfo, err := FindAllDeviceByDevId(Dev_id)
	if err != nil {
		return resultList
	}

	if deviceInfo == nil {
		return resultList
	}

	if deviceInfo.ChannelInfo.IsTransfer() {
		for _, ele := range sqlite_conf_table.TransferTagInfoList() {
			if ele.DeviceInfo.Dev_id == Dev_id {
				resultList = append(resultList, ele)
			}
		}

		return resultList
	}

	for _, ele := range sqlite_conf_table.TagInfoList() {
		if ele.DeviceInfo.Dev_id == Dev_id {
			resultList = append(resultList, ele)
		}
	}

	return resultList
}

func FindAllTagByTagId(Tag_id string) (*conf_table_define.TagInfo, error) {

	tagConfInfo := sqlite_conf_table.FindTagInfoByTagId(Tag_id)
	if tagConfInfo != nil {
		return tagConfInfo, nil
	}

	for _, ele := range sqlite_conf_table.TransferTagInfoList() {
		if ele.Tag_id == Tag_id {
			return ele, nil
		}
	}

	return nil, sys_error.NOT_FOUND_ERR
}

// FindTagByName 根据名称获取, 注意不包含转发标签
func FindTagByName(Tag_name string) (*conf_table_define.TagInfo, error) {
	info := sqlite_conf_table.TagInfoList()[Tag_name]
	if info != nil {
		return info, nil
	}
	return nil, sys_error.NOT_FOUND_ERR
}

func FindAllTagByTagDesc(Dev_id string, Tag_desc string) []*conf_table_define.TagInfo {

	resultList := make([]*conf_table_define.TagInfo, 0, 30)

	devInfo, err := FindAllDeviceByDevId(Dev_id)
	if err != nil {
		return resultList
	}

	if !devInfo.ChannelInfo.IsTransfer() {
		for _, ele := range sqlite_conf_table.TagInfoList() {
			if ele.DeviceInfo.Dev_id != Dev_id {
				continue
			}
			if ele.Tag_desc == Tag_desc {
				resultList = append(resultList, ele)
			}
		}

		return resultList
	}

	transferTagMap := sqlite_conf_table.FindTransferTagInfoByDevId(Dev_id)
	if transferTagMap == nil || len(transferTagMap) <= 0 {
		return resultList
	}
	for _, ele := range transferTagMap {
		if ele.DeviceInfo.Dev_id != Dev_id {
			continue
		}
		if ele.Tag_desc == Tag_desc {
			resultList = append(resultList, ele)
		}
	}

	return resultList
}

func FindAllTagByObjAddr(Dev_id string, obj_addr string) []*conf_table_define.TagInfo {
	resultList := make([]*conf_table_define.TagInfo, 0, 30)

	devInfo, err := FindAllDeviceByDevId(Dev_id)
	if err != nil {
		return resultList
	}

	if !devInfo.ChannelInfo.IsTransfer() {
		for _, ele := range sqlite_conf_table.TagInfoList() {
			if ele.DeviceInfo.Dev_id != Dev_id {
				continue
			}
			if ele.Obj_addr == obj_addr {
				resultList = append(resultList, ele)
			}
		}

		return resultList
	}

	transferTagMap := sqlite_conf_table.FindTransferTagInfoByDevId(Dev_id)
	if transferTagMap == nil || len(transferTagMap) <= 0 {
		return resultList
	}
	for _, ele := range transferTagMap {
		if ele.DeviceInfo.Dev_id != Dev_id {
			continue
		}
		if ele.Obj_addr == obj_addr {
			resultList = append(resultList, ele)
		}
	}

	return resultList
}

func FindAllValidTagByChlId(Chl_id string) []*conf_table_define.TagInfo {
	resultList := make([]*conf_table_define.TagInfo, 0, 1200)

	channelConfInfo, err := FindAllChannelByChlId(Chl_id)
	if err != nil {
		return resultList
	}

	if channelConfInfo == nil || !channelConfInfo.IsValid() {
		return resultList
	}

	if channelConfInfo.IsTransfer() {
		for _, ele := range sqlite_conf_table.TransferTagInfoList() {
			if ele.DeviceInfo.ChannelInfo.Chl_id == Chl_id && ele.DeviceInfo.IsValid() {
				resultList = append(resultList, ele)
			}
		}
		return resultList
	}

	for _, ele := range sqlite_conf_table.TagInfoList() {
		if ele.DeviceInfo.ChannelInfo.Chl_id == Chl_id && ele.DeviceInfo.IsValid() {
			resultList = append(resultList, ele)
		}
	}

	return resultList
}

// FindTransferTag 转发标签信息
func FindTransferTag() []*conf_table_define.TagInfo {
	list := sqlite_conf_table.TransferTagInfoList()
	if list == nil {
		list = make([]*conf_table_define.TagInfo, 0)
	}
	return list
}

func FindAllTagByName(dev_id string, Tag_name string) (*conf_table_define.TagInfo, error) {

	devInfo, err := FindAllDeviceByDevId(dev_id)
	if err != nil {
		return nil, err
	}

	if devInfo.ChannelInfo.IsTransfer() {
		tag := sqlite_conf_table.FindTransferTagInfoByTagName(dev_id, Tag_name)
		if tag == nil {
			return nil, sys_error.NOT_FOUND_ERR
		}
		return tag, nil
	}

	return FindTagByName(Tag_name)
}

// FindAllDevice 获取设备配置 不包含转发
func FindAllDevice() []*conf_table_define.DeviceInfo {
	resultList := make([]*conf_table_define.DeviceInfo, 0, 12)
	for _, ele := range sqlite_conf_table.DeviceConfInfoList() {
		resultList = append(resultList, ele)
	}
	return resultList
}

// FindDevice 不包含转发
func FindDevice() []*conf_table_define.DeviceInfo {
	resultList := make([]*conf_table_define.DeviceInfo, 0, 12)
	for _, ele := range sqlite_conf_table.DeviceConfInfoList() {
		if !ele.ChannelInfo.IsTransfer() {
			resultList = append(resultList, ele)
		}
	}
	return resultList
}

func FindTransferDevice() []*conf_table_define.DeviceInfo {
	resultList := make([]*conf_table_define.DeviceInfo, 0, 12)
	for _, ele := range sqlite_conf_table.DeviceConfInfoList() {
		if ele.ChannelInfo.IsTransfer() {
			resultList = append(resultList, ele)
		}
	}
	return resultList
}

// FindAllDeviceByChlId 获取 设备配置 根据 ChannelInfo.Chl_id 查询
func FindAllDeviceByChlId(Chl_id string) []*conf_table_define.DeviceInfo {
	resultList := make([]*conf_table_define.DeviceInfo, 0, 12)
	for _, ele := range sqlite_conf_table.DeviceConfInfoList() {
		if ele.ChannelInfo.Chl_id == Chl_id {
			resultList = append(resultList, ele)
		}
	}
	return resultList
}

// FindAllValidDeviceByChlId 获取有效的设备
func FindAllValidDeviceByChlId(Chl_id string) []*conf_table_define.DeviceInfo {
	resultList := make([]*conf_table_define.DeviceInfo, 0, 12)
	for _, ele := range sqlite_conf_table.DeviceConfInfoList() {
		if ele.ChannelInfo.Chl_id == Chl_id && ele.IsValid() {
			resultList = append(resultList, ele)
		}
	}
	return resultList
}

func FindAllDeviceByDevId(dev_id string) (*conf_table_define.DeviceInfo, error) {
	if info, ok := sqlite_conf_table.DeviceConfInfoList()[dev_id]; ok {
		return info, nil
	}
	return nil, sys_error.NOT_FOUND_ERR
}

func FindAllDeviceByDevName(Dev_name string) (*conf_table_define.DeviceInfo, error) {
	for _, ele := range sqlite_conf_table.DeviceConfInfoList() {
		if ele.Dev_name == Dev_name {
			return ele, nil
		}
	}
	return nil, sys_error.NOT_FOUND_ERR
}

// ProtocolList 协议获取
func ProtocolList(chl_id string) []*conf_table_define.ProtocolInfo {
	list := sqlite_conf_table.ProtocolConfInfoList(chl_id)
	if list == nil {
		list = make([]*conf_table_define.ProtocolInfo, 0)
	}
	return list
}

// FindFormula 获取 计算公式
func FindFormula() []*conf_table_define.FormulaInfo {
	list := make([]*conf_table_define.FormulaInfo, 0, 1)
	//todo
	return list
}

// FindScript 获取脚本
func FindScript() []*conf_table_define.ScriptInfo {
	list := make([]*conf_table_define.ScriptInfo, 0, 1)
	//todo
	return list
}
